From 9e11829aa9f1ce006bb26570e45920b261f87b51 Mon Sep 17 00:00:00 2001 From: "kaf24@firebug.cl.cam.ac.uk" Date: Thu, 5 May 2005 17:58:59 +0000 Subject: [PATCH] bitkeeper revision 1.1389.5.21 (427a5ee3rBlRFupS4xBvv_nWVHQlsA) Clean up IO-APIC handling in domain0, and the hypercall interface exported by Xen (inc. removal of PCI-related calls). This hopefully fixes acpi=off. Signed-off-by: Keir Fraser --- .rootkeys | 5 +- .../arch/xen/i386/kernel/apic.c | 32 +- .../arch/xen/i386/kernel/io_apic.c | 111 ++- .../include/asm-xen/asm-i386/io_apic.h | 229 ----- tools/libxc/xc_physdev.c | 12 +- xen/arch/ia64/domain.c | 8 - xen/arch/ia64/xenmisc.c | 27 - xen/arch/ia64/xensetup.c | 3 - xen/arch/x86/domain.c | 3 + xen/arch/x86/io_apic.c | 84 +- xen/arch/x86/physdev.c | 145 +++ xen/common/Makefile | 1 - xen/common/dom0_ops.c | 11 - xen/common/domain.c | 11 - xen/common/physdev.c | 832 ------------------ xen/drivers/char/serial.c | 7 +- xen/include/asm-x86/config.h | 2 - xen/include/{xen => asm-x86}/physdev.h | 2 - xen/include/public/dom0_ops.h | 14 - xen/include/public/physdev.h | 55 +- xen/include/xen/sched.h | 4 - 21 files changed, 343 insertions(+), 1255 deletions(-) delete mode 100644 linux-2.6.11-xen-sparse/include/asm-xen/asm-i386/io_apic.h create mode 100644 xen/arch/x86/physdev.c delete mode 100644 xen/common/physdev.c rename xen/include/{xen => asm-x86}/physdev.h (84%) diff --git a/.rootkeys b/.rootkeys index 5bfc5e1824..cfb01fda7d 100644 --- a/.rootkeys +++ b/.rootkeys @@ -352,7 +352,6 @@ 4118b6a418gnL6AZsTdglC92YGqYTg linux-2.6.11-xen-sparse/include/asm-xen/asm-i386/highmem.h 42539fb5A9hsS3NFQ-2VY4y1TONZZQ linux-2.6.11-xen-sparse/include/asm-xen/asm-i386/hypercall.h 40f5623aJVXQwpJMOLE99XgvGsfQ8Q linux-2.6.11-xen-sparse/include/asm-xen/asm-i386/io.h -42778a69MXZVxch4pQqYsMPS0WnNSg linux-2.6.11-xen-sparse/include/asm-xen/asm-i386/io_apic.h 40f5623aKXkBBxgpLx2NcvkncQ1Yyw linux-2.6.11-xen-sparse/include/asm-xen/asm-i386/mach-xen/irq_vectors.h 40f5623aDMCsWOFO0jktZ4e8sjwvEg linux-2.6.11-xen-sparse/include/asm-xen/asm-i386/mach-xen/setup_arch_post.h 40f5623arsFXkGdPvIqvFi3yFXGR0Q linux-2.6.11-xen-sparse/include/asm-xen/asm-i386/mach-xen/setup_arch_pre.h @@ -1216,6 +1215,7 @@ 41aaf567a36esU-rUK7twPiv-yTFyw xen/arch/x86/mtrr/mtrr.h 41aaf567DcTL6pqVtLZJI5cSryyA1A xen/arch/x86/mtrr/state.c 3f12cff65EV3qOG2j37Qm0ShgvXGRw xen/arch/x86/nmi.c +4051bcecFeq4DE70p4zGO5setf47CA xen/arch/x86/physdev.c 3ddb79bc7KxGCEJsgBnkDX7XjD_ZEQ xen/arch/x86/rwlock.c 3ddb79bcrD6Z_rUvSDgrvjyb4846Eg xen/arch/x86/setup.c 405b8599xI_PoEr3zZoJ2on-jdn7iw xen/arch/x86/shadow.c @@ -1259,7 +1259,6 @@ 41a61536SZbR6cj1ukWTb0DYU-vz9w xen/common/multicall.c 3ddb79bdD4SLmmdMD7yLW5HcUWucXw xen/common/page_alloc.c 3e54c38dkHAev597bPr71-hGzTdocg xen/common/perfc.c -4051bcecFeq4DE70p4zGO5setf47CA xen/common/physdev.c 3ddb79bdHqdQpATqC0rmUZNbsb6L6A xen/common/resource.c 40589968dD2D1aejwSOvrROg7fOvGQ xen/common/sched_bvt.c 3e397e6619PgAfBbw2XFbXkewvUWgw xen/common/schedule.c @@ -1354,6 +1353,7 @@ 41a61536MFhNalgbVmYGXAhQsPTZNw xen/include/asm-x86/multicall.h 3ddb79c3xjYnrv5t3VqYlR4tNEOl4Q xen/include/asm-x86/page.h 3ddb79c3ysKUbxZuwKBRK3WXU2TlEg xen/include/asm-x86/pci.h +42422fb0FVX-TJkSvAXnbfwMf19XFA xen/include/asm-x86/physdev.h 3ddb79c2QF5-pZGzuX4QukPCDAl59A xen/include/asm-x86/processor.h 40cf1596bim9F9DNdV75klgRSZ6Y2A xen/include/asm-x86/regs.h 3ddb79c2plf7ciNgoNjU-RsbUzawsw xen/include/asm-x86/rwlock.h @@ -1436,7 +1436,6 @@ 3ddb79c0MOVXq8qZDQRGb6z64_xAwg xen/include/xen/pci_ids.h 3e54c38dlSCVdyVM4PKcrSfzLLxWUQ xen/include/xen/perfc.h 3e54c38de9SUSYSAwxDf_DwkpAnQFA xen/include/xen/perfc_defn.h -42422fb0FVX-TJkSvAXnbfwMf19XFA xen/include/xen/physdev.h 3ddb79c04nQVR3EYM5L4zxDV_MCo1g xen/include/xen/prefetch.h 3e4540ccU1sgCx8seIMGlahmMfv7yQ xen/include/xen/reboot.h 40589969nPq3DMzv24RDb5LXE9brHw xen/include/xen/sched-if.h diff --git a/linux-2.6.11-xen-sparse/arch/xen/i386/kernel/apic.c b/linux-2.6.11-xen-sparse/arch/xen/i386/kernel/apic.c index 4ca346bc49..5f071a5956 100644 --- a/linux-2.6.11-xen-sparse/arch/xen/i386/kernel/apic.c +++ b/linux-2.6.11-xen-sparse/arch/xen/i386/kernel/apic.c @@ -16,8 +16,32 @@ #include #include -#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "io_ports.h" + +/* + * Debug level + */ int apic_verbosity; int get_physical_broadcast(void) @@ -49,5 +73,11 @@ void ack_bad_irq(unsigned int irq) */ int __init APIC_init_uniprocessor (void) { +#ifdef CONFIG_X86_IO_APIC + if (smp_found_config) + if (!skip_ioapic_setup && nr_ioapics) + setup_IO_APIC(); +#endif + return 0; } diff --git a/linux-2.6.11-xen-sparse/arch/xen/i386/kernel/io_apic.c b/linux-2.6.11-xen-sparse/arch/xen/i386/kernel/io_apic.c index 667d11e10b..6fbaa19613 100644 --- a/linux-2.6.11-xen-sparse/arch/xen/i386/kernel/io_apic.c +++ b/linux-2.6.11-xen-sparse/arch/xen/i386/kernel/io_apic.c @@ -37,18 +37,56 @@ #include #include #include -#include -#include #include #include "io_ports.h" -int (*ioapic_renumber_irq)(int ioapic, int irq); -atomic_t irq_mis_count; +#ifdef CONFIG_XEN + +#include +#include + +/* Fake i8259 */ +#define make_8259A_irq(_irq) (io_apic_irqs &= ~(1UL<<(_irq))) +#define disable_8259A_irq(_irq) ((void)0) +#define i8259A_irq_pending(_irq) (0) unsigned long io_apic_irqs; +static inline unsigned int xen_io_apic_read(unsigned int apic, unsigned int reg) +{ + physdev_op_t op; + int ret; + + op.cmd = PHYSDEVOP_APIC_READ; + op.u.apic_op.apic = mp_ioapics[apic].mpc_apicid; + op.u.apic_op.offset = reg; + ret = HYPERVISOR_physdev_op(&op); + if (ret) + return ret; + return op.u.apic_op.value; +} + +static inline void xen_io_apic_write(unsigned int apic, unsigned int reg, unsigned int value) +{ + physdev_op_t op; + + op.cmd = PHYSDEVOP_APIC_WRITE; + op.u.apic_op.apic = mp_ioapics[apic].mpc_apicid; + op.u.apic_op.offset = reg; + op.u.apic_op.value = value; + HYPERVISOR_physdev_op(&op); +} + +#define io_apic_read(a,r) xen_io_apic_read(a,r) +#define io_apic_write(a,r,v) xen_io_apic_write(a,r,v) + +#endif /* CONFIG_XEN */ + +int (*ioapic_renumber_irq)(int ioapic, int irq); +atomic_t irq_mis_count; + static DEFINE_SPINLOCK(ioapic_lock); /* @@ -111,6 +149,7 @@ static void add_pin_to_irq(unsigned int irq, int apic, int pin) entry->pin = pin; } +#ifndef CONFIG_XEN /* * Reroute an IRQ to a different pin. */ @@ -247,6 +286,9 @@ static void set_ioapic_affinity_irq(unsigned int irq, cpumask_t cpumask) } spin_unlock_irqrestore(&ioapic_lock, flags); } +#else +#define clear_IO_APIC() ((void)0) +#endif #if defined(CONFIG_IRQBALANCE) # include /* kernel_thread() */ @@ -668,9 +710,7 @@ static inline void move_irq(int irq) { } #ifndef CONFIG_SMP void fastcall send_IPI_self(int vector) { -#if 1 - return; -#else +#ifndef CONFIG_XEN unsigned int cfg; /* @@ -686,7 +726,6 @@ void fastcall send_IPI_self(int vector) } #endif /* !CONFIG_SMP */ - /* * support for broken MP BIOSs, enables hand-redirection of PIRQ0-7 to * specific CPU-side IRQs. @@ -752,6 +791,7 @@ static int find_irq_entry(int apic, int pin, int type) return -1; } +#ifndef CONFIG_XEN /* * Find the pin to which IRQ[irq] (ISA) is connected */ @@ -774,6 +814,7 @@ static int find_isa_irq_pin(int irq, int type) } return -1; } +#endif /* * Find a specific PCI IRQ entry. @@ -821,6 +862,7 @@ int IO_APIC_get_PCI_irq_vector(int bus, int slot, int pin) return best_guess; } +#ifndef CONFIG_XEN /* * This function currently is only a helper for the i386 smp boot process where * we need to reprogram the ioredtbls to cater for the cpus which have come online @@ -844,6 +886,7 @@ void __init setup_ioapic_dest(void) } } +#endif /* !CONFIG_XEN */ /* * EISA Edge/Level control register, ELCR @@ -1133,7 +1176,7 @@ static inline int IO_APIC_irq_trigger(int irq) } /* irq_vectors is indexed by the sum of all RTEs in all I/O APICs. */ -u8 irq_vector[NR_IRQ_VECTORS] = { FIRST_DEVICE_VECTOR , 0 }; +u8 irq_vector[NR_IRQ_VECTORS]; /* = { FIRST_DEVICE_VECTOR , 0 }; */ int assign_irq_vector(int irq) { @@ -1157,6 +1200,7 @@ int assign_irq_vector(int irq) return current_vector; } +#ifndef CONFIG_XEN static struct hw_interrupt_type ioapic_level_type; static struct hw_interrupt_type ioapic_edge_type; @@ -1172,20 +1216,19 @@ static inline void ioapic_register_intr(int irq, int vector, unsigned long trigg irq_desc[vector].handler = &ioapic_level_type; else irq_desc[vector].handler = &ioapic_edge_type; -#if 0 set_intr_gate(vector, interrupt[vector]); -#endif } else { if ((trigger == IOAPIC_AUTO && IO_APIC_irq_trigger(irq)) || trigger == IOAPIC_LEVEL) irq_desc[irq].handler = &ioapic_level_type; else irq_desc[irq].handler = &ioapic_edge_type; -#if 0 set_intr_gate(vector, interrupt[irq]); -#endif } } +#else +#define ioapic_register_intr(_irq,_vector,_trigger) ((void)0) +#endif void __init setup_IO_APIC_irqs(void) { @@ -1241,7 +1284,7 @@ void __init setup_IO_APIC_irqs(void) else add_pin_to_irq(irq, apic, pin); - if (!apic && !IO_APIC_IRQ(irq)) + if (/*!apic &&*/ !IO_APIC_IRQ(irq)) continue; if (IO_APIC_IRQ(irq)) { @@ -1249,10 +1292,8 @@ void __init setup_IO_APIC_irqs(void) entry.vector = vector; ioapic_register_intr(irq, vector, IOAPIC_AUTO); -#if 0 if (!apic && (irq < 16)) disable_8259A_irq(irq); -#endif } spin_lock_irqsave(&ioapic_lock, flags); io_apic_write(apic, 0x11+2*pin, *(((int *)&entry)+1)); @@ -1268,6 +1309,7 @@ void __init setup_IO_APIC_irqs(void) /* * Set up the 8259A-master output pin: */ +#ifndef CONFIG_XEN void __init setup_ExtINT_IRQ0_pin(unsigned int pin, int vector) { struct IO_APIC_route_entry entry; @@ -1275,9 +1317,7 @@ void __init setup_ExtINT_IRQ0_pin(unsigned int pin, int vector) memset(&entry,0,sizeof(entry)); -#if 0 disable_8259A_irq(0); -#endif /* mask LVT0 */ apic_write_around(APIC_LVT0, APIC_LVT_MASKED | APIC_DM_EXTINT); @@ -1308,9 +1348,7 @@ void __init setup_ExtINT_IRQ0_pin(unsigned int pin, int vector) io_apic_write(0, 0x10+2*pin, *(((int *)&entry)+0)); spin_unlock_irqrestore(&ioapic_lock, flags); -#if 0 enable_8259A_irq(0); -#endif } static inline void UNEXPECTED_IO_APIC(void) @@ -1489,7 +1527,6 @@ static void print_APIC_bitfield (int base) void /*__init*/ print_local_APIC(void * dummy) { -#if 0 unsigned int v, ver, maxlvt; if (apic_verbosity == APIC_QUIET) @@ -1569,7 +1606,6 @@ void /*__init*/ print_local_APIC(void * dummy) v = apic_read(APIC_TDCR); printk(KERN_DEBUG "... APIC TDCR: %08x\n", v); printk("\n"); -#endif } void print_all_local_APICs (void) @@ -1609,6 +1645,9 @@ void /*__init*/ print_PIC(void) v = inb(0x4d1) << 8 | inb(0x4d0); printk(KERN_DEBUG "... PIC ELCR: %04x\n", v); } +#else +void __init print_IO_APIC(void) { } +#endif /* !CONFIG_XEN */ static void __init enable_IO_APIC(void) { @@ -1650,7 +1689,7 @@ void disable_IO_APIC(void) */ clear_IO_APIC(); -#if 0 +#ifndef CONFIG_XEN disconnect_bsp_APIC(); #endif } @@ -1662,7 +1701,7 @@ void disable_IO_APIC(void) * by Matt Domsch Tue Dec 21 12:25:05 CST 1999 */ -#ifndef CONFIG_X86_NUMAQ +#if !defined(CONFIG_XEN) && !defined(CONFIG_X86_NUMAQ) static void __init setup_ioapic_ids_from_mpc(void) { union IO_APIC_reg_00 reg_00; @@ -1769,6 +1808,7 @@ static void __init setup_ioapic_ids_from_mpc(void) static void __init setup_ioapic_ids_from_mpc(void) { } #endif +#ifndef CONFIG_XEN /* * There is a nasty bug in some older SMP boards, their mptable lies * about the timer IRQ. We do the following to work around the situation: @@ -1826,13 +1866,11 @@ static unsigned int startup_edge_ioapic_irq(unsigned int irq) unsigned long flags; spin_lock_irqsave(&ioapic_lock, flags); -#if 0 if (irq < 16) { disable_8259A_irq(irq); if (i8259A_irq_pending(irq)) was_pending = 1; } -#endif __unmask_IO_APIC_irq(irq); spin_unlock_irqrestore(&ioapic_lock, flags); @@ -1995,6 +2033,7 @@ static struct hw_interrupt_type ioapic_level_type = { .end = end_level_ioapic, .set_affinity = set_ioapic_affinity, }; +#endif /* !CONFIG_XEN */ static inline void init_IO_APIC_traps(void) { @@ -2024,17 +2063,18 @@ static inline void init_IO_APIC_traps(void) * so default to an old-fashioned 8259 * interrupt if we can.. */ -#if 0 if (irq < 16) make_8259A_irq(irq); +#ifndef CONFIG_XEN else -#endif /* Strange. Oh, well.. */ irq_desc[irq].handler = &no_irq_type; +#endif } } } +#ifndef CONFIG_XEN static void enable_lapic_irq (unsigned int irq) { unsigned long v; @@ -2081,9 +2121,7 @@ static void setup_nmi (void) */ apic_printk(APIC_VERBOSE, KERN_INFO "activating NMI Watchdog ..."); -#if 0 on_each_cpu(enable_NMI_through_LVT0, NULL, 1, 1); -#endif apic_printk(APIC_VERBOSE, " done.\n"); } @@ -2158,7 +2196,6 @@ static inline void unlock_ExtINT_logic(void) */ static inline void check_timer(void) { -#if 0 int pin1, pin2; int vector; @@ -2265,8 +2302,10 @@ static inline void check_timer(void) printk(" failed :(.\n"); panic("IO-APIC + timer doesn't work! Boot with apic=debug and send a " "report. Then try booting with the 'noapic' option"); -#endif } +#else +#define check_timer() ((void)0) +#endif /* * @@ -2293,7 +2332,7 @@ void __init setup_IO_APIC(void) */ if (!acpi_ioapic) setup_ioapic_ids_from_mpc(); -#if 0 +#ifndef CONFIG_XEN sync_Arb_IDs(); #endif setup_IO_APIC_irqs(); @@ -2417,6 +2456,7 @@ device_initcall(ioapic_init_sysfs); int __init io_apic_get_unique_id (int ioapic, int apic_id) { +#ifndef CONFIG_XEN union IO_APIC_reg_00 reg_00; static physid_mask_t apic_id_map = PHYSID_MASK_NONE; physid_mask_t tmp; @@ -2445,7 +2485,6 @@ int __init io_apic_get_unique_id (int ioapic, int apic_id) apic_id = reg_00.bits.ID; } -#if 0 /* * Every APIC in a system must have a unique ID or we get lots of nice * 'stuck on smp_invalidate_needed IPI wait' messages. @@ -2481,10 +2520,10 @@ int __init io_apic_get_unique_id (int ioapic, int apic_id) if (reg_00.bits.ID != apic_id) panic("IOAPIC[%d]: Unable change apic_id!\n", ioapic); } -#endif apic_printk(APIC_VERBOSE, KERN_INFO "IOAPIC[%d]: Assigned apic_id %d\n", ioapic, apic_id); +#endif /* !CONFIG_XEN */ return apic_id; } @@ -2555,12 +2594,10 @@ int io_apic_set_pci_routing (int ioapic, int pin, int irq, int edge_level, int a mp_ioapics[ioapic].mpc_apicid, pin, entry.vector, irq, edge_level, active_high_low); -#ifndef CONFIG_XEN ioapic_register_intr(irq, entry.vector, edge_level); if (!ioapic && (irq < 16)) disable_8259A_irq(irq); -#endif spin_lock_irqsave(&ioapic_lock, flags); io_apic_write(ioapic, 0x11+2*pin, *(((int *)&entry)+1)); diff --git a/linux-2.6.11-xen-sparse/include/asm-xen/asm-i386/io_apic.h b/linux-2.6.11-xen-sparse/include/asm-xen/asm-i386/io_apic.h deleted file mode 100644 index bc10fff7de..0000000000 --- a/linux-2.6.11-xen-sparse/include/asm-xen/asm-i386/io_apic.h +++ /dev/null @@ -1,229 +0,0 @@ -#ifndef __ASM_IO_APIC_H -#define __ASM_IO_APIC_H - -#include -#include -#include - -#include -#include - -/* - * Intel IO-APIC support for SMP and UP systems. - * - * Copyright (C) 1997, 1998, 1999, 2000 Ingo Molnar - */ - -#ifdef CONFIG_X86_IO_APIC - -#ifdef CONFIG_PCI_MSI -static inline int use_pci_vector(void) {return 1;} -static inline void disable_edge_ioapic_vector(unsigned int vector) { } -static inline void mask_and_ack_level_ioapic_vector(unsigned int vector) { } -static inline void end_edge_ioapic_vector (unsigned int vector) { } -#define startup_level_ioapic startup_level_ioapic_vector -#define shutdown_level_ioapic mask_IO_APIC_vector -#define enable_level_ioapic unmask_IO_APIC_vector -#define disable_level_ioapic mask_IO_APIC_vector -#define mask_and_ack_level_ioapic mask_and_ack_level_ioapic_vector -#define end_level_ioapic end_level_ioapic_vector -#define set_ioapic_affinity set_ioapic_affinity_vector - -#define startup_edge_ioapic startup_edge_ioapic_vector -#define shutdown_edge_ioapic disable_edge_ioapic_vector -#define enable_edge_ioapic unmask_IO_APIC_vector -#define disable_edge_ioapic disable_edge_ioapic_vector -#define ack_edge_ioapic ack_edge_ioapic_vector -#define end_edge_ioapic end_edge_ioapic_vector -#else -static inline int use_pci_vector(void) {return 0;} -static inline void disable_edge_ioapic_irq(unsigned int irq) { } -static inline void mask_and_ack_level_ioapic_irq(unsigned int irq) { } -static inline void end_edge_ioapic_irq (unsigned int irq) { } -#define startup_level_ioapic startup_level_ioapic_irq -#define shutdown_level_ioapic mask_IO_APIC_irq -#define enable_level_ioapic unmask_IO_APIC_irq -#define disable_level_ioapic mask_IO_APIC_irq -#define mask_and_ack_level_ioapic mask_and_ack_level_ioapic_irq -#define end_level_ioapic end_level_ioapic_irq -#define set_ioapic_affinity set_ioapic_affinity_irq - -#define startup_edge_ioapic startup_edge_ioapic_irq -#define shutdown_edge_ioapic disable_edge_ioapic_irq -#define enable_edge_ioapic unmask_IO_APIC_irq -#define disable_edge_ioapic disable_edge_ioapic_irq -#define ack_edge_ioapic ack_edge_ioapic_irq -#define end_edge_ioapic end_edge_ioapic_irq -#endif - -#define IO_APIC_BASE(idx) \ - ((volatile int *)(__fix_to_virt(FIX_IO_APIC_BASE_0 + idx) \ - + (mp_ioapics[idx].mpc_apicaddr & ~PAGE_MASK))) - -/* - * The structure of the IO-APIC: - */ -union IO_APIC_reg_00 { - u32 raw; - struct { - u32 __reserved_2 : 14, - LTS : 1, - delivery_type : 1, - __reserved_1 : 8, - ID : 8; - } __attribute__ ((packed)) bits; -}; - -union IO_APIC_reg_01 { - u32 raw; - struct { - u32 version : 8, - __reserved_2 : 7, - PRQ : 1, - entries : 8, - __reserved_1 : 8; - } __attribute__ ((packed)) bits; -}; - -union IO_APIC_reg_02 { - u32 raw; - struct { - u32 __reserved_2 : 24, - arbitration : 4, - __reserved_1 : 4; - } __attribute__ ((packed)) bits; -}; - -union IO_APIC_reg_03 { - u32 raw; - struct { - u32 boot_DT : 1, - __reserved_1 : 31; - } __attribute__ ((packed)) bits; -}; - -/* - * # of IO-APICs and # of IRQ routing registers - */ -extern int nr_ioapics; -extern int nr_ioapic_registers[MAX_IO_APICS]; - -enum ioapic_irq_destination_types { - dest_Fixed = 0, - dest_LowestPrio = 1, - dest_SMI = 2, - dest__reserved_1 = 3, - dest_NMI = 4, - dest_INIT = 5, - dest__reserved_2 = 6, - dest_ExtINT = 7 -}; - -struct IO_APIC_route_entry { - __u32 vector : 8, - delivery_mode : 3, /* 000: FIXED - * 001: lowest prio - * 111: ExtINT - */ - dest_mode : 1, /* 0: physical, 1: logical */ - delivery_status : 1, - polarity : 1, - irr : 1, - trigger : 1, /* 0: edge, 1: level */ - mask : 1, /* 0: enabled, 1: disabled */ - __reserved_2 : 15; - - union { struct { __u32 - __reserved_1 : 24, - physical_dest : 4, - __reserved_2 : 4; - } physical; - - struct { __u32 - __reserved_1 : 24, - logical_dest : 8; - } logical; - } dest; - -} __attribute__ ((packed)); - -/* - * MP-BIOS irq configuration table structures: - */ - -/* I/O APIC entries */ -extern struct mpc_config_ioapic mp_ioapics[MAX_IO_APICS]; - -/* # of MP IRQ source entries */ -extern int mp_irq_entries; - -/* MP IRQ source entries */ -extern struct mpc_config_intsrc mp_irqs[MAX_IRQ_SOURCES]; - -/* non-0 if default (table-less) MP configuration */ -extern int mpc_default_type; - -static inline unsigned int io_apic_read(unsigned int apic, unsigned int reg) -{ - physdev_op_t op; - int ret; - - op.cmd = PHYSDEVOP_APIC_READ; - op.u.apic_op.apic = apic; - op.u.apic_op.offset = reg; - ret = HYPERVISOR_physdev_op(&op); - if (ret) - return ret; - return op.u.apic_op.value; -} - -static inline void io_apic_write(unsigned int apic, unsigned int reg, unsigned int value) -{ - physdev_op_t op; - - op.cmd = PHYSDEVOP_APIC_WRITE; - op.u.apic_op.apic = apic; - op.u.apic_op.offset = reg; - op.u.apic_op.value = value; - HYPERVISOR_physdev_op(&op); -} - -/* - * Re-write a value: to be used for read-modify-write - * cycles where the read already set up the index register. - * - * Older SiS APIC requires we rewrite the index regiser - */ -extern int sis_apic_bug; -static inline void io_apic_modify(unsigned int apic, unsigned int reg, unsigned int value) -{ - if (sis_apic_bug) - *IO_APIC_BASE(apic) = reg; - *(IO_APIC_BASE(apic)+4) = value; -} - -/* 1 if "noapic" boot option passed */ -extern int skip_ioapic_setup; - -/* - * If we use the IO-APIC for IRQ routing, disable automatic - * assignment of PCI IRQ's. - */ -#define io_apic_assign_pci_irqs (mp_irq_entries && !skip_ioapic_setup && io_apic_irqs) - -#ifdef CONFIG_ACPI_BOOT -extern int io_apic_get_unique_id (int ioapic, int apic_id); -extern int io_apic_get_version (int ioapic); -extern int io_apic_get_redir_entries (int ioapic); -extern int io_apic_set_pci_routing (int ioapic, int pin, int irq, int edge_level, int active_high_low); -#endif /*CONFIG_ACPI_BOOT*/ - -extern int (*ioapic_renumber_irq)(int ioapic, int irq); - -#else /* !CONFIG_X86_IO_APIC */ -#define io_apic_assign_pci_irqs 0 -#endif - -extern int assign_irq_vector(int irq); - -#endif diff --git a/tools/libxc/xc_physdev.c b/tools/libxc/xc_physdev.c index ba5dd9ccdc..94fe34dc52 100644 --- a/tools/libxc/xc_physdev.c +++ b/tools/libxc/xc_physdev.c @@ -16,14 +16,6 @@ int xc_physdev_pci_access_modify(int xc_handle, int func, int enable) { - dom0_op_t op; - - op.cmd = DOM0_PCIDEV_ACCESS; - op.u.pcidev_access.domain = (domid_t)domid; - op.u.pcidev_access.bus = bus; - op.u.pcidev_access.dev = dev; - op.u.pcidev_access.func = func; - op.u.pcidev_access.enable = enable; - - return do_dom0_op(xc_handle, &op); + errno = ENOSYS; + return -1; } diff --git a/xen/arch/ia64/domain.c b/xen/arch/ia64/domain.c index 056e9a711b..9f0d9d20ba 100644 --- a/xen/arch/ia64/domain.c +++ b/xen/arch/ia64/domain.c @@ -621,8 +621,6 @@ int construct_dom0(struct domain *d, unsigned long pkern_entry; unsigned long pkern_end; - extern void physdev_init_dom0(struct domain *); - //printf("construct_dom0: starting\n"); /* Sanity! */ #ifndef CLONE_DOMAIN0 @@ -755,12 +753,6 @@ int construct_dom0(struct domain *d, #endif console_endboot(strstr(cmdline, "tty0") != NULL); - /* DOM0 gets access to everything. */ -#ifdef CLONE_DOMAIN0 -if (d == dom0) -#endif - physdev_init_dom0(d); - set_bit(DF_CONSTRUCTED, &d->d_flags); new_thread(ed, pkern_entry, 0, 0); diff --git a/xen/arch/ia64/xenmisc.c b/xen/arch/ia64/xenmisc.c index 241072ee85..8d94e3f536 100644 --- a/xen/arch/ia64/xenmisc.c +++ b/xen/arch/ia64/xenmisc.c @@ -149,33 +149,6 @@ void dump_pageframe_info(struct domain *d) printk("dump_pageframe_info not implemented\n"); } -/////////////////////////////// -// from common/physdev.c -/////////////////////////////// -void -physdev_init_dom0(struct domain *d) -{ -} - -int -physdev_pci_access_modify(domid_t id, int bus, int dev, int func, int enable) -{ - return -EINVAL; -} - -void physdev_modify_ioport_access_range(struct domain *d, int enable, - int port, int num) -{ - printk("physdev_modify_ioport_access_range not implemented\n"); - dummy(); -} - -void physdev_destroy_state(struct domain *d) -{ - printk("physdev_destroy_state not implemented\n"); - dummy(); -} - /////////////////////////////// // called from arch/ia64/head.S /////////////////////////////// diff --git a/xen/arch/ia64/xensetup.c b/xen/arch/ia64/xensetup.c index 2c24a872ea..7d497ea40c 100644 --- a/xen/arch/ia64/xensetup.c +++ b/xen/arch/ia64/xensetup.c @@ -69,9 +69,6 @@ unsigned char opt_pdb[10] = "none"; unsigned int opt_tbuf_size = 10; /* opt_sched: scheduler - default to Borrowed Virtual Time */ char opt_sched[10] = "bvt"; -/* opt_physdev_dom0_hide: list of PCI slots to hide from domain 0. */ -/* Format is '(%02x:%02x.%1x)(%02x:%02x.%1x)' and so on. */ -char opt_physdev_dom0_hide[200] = ""; /* opt_leveltrigger, opt_edgetrigger: Force an IO-APIC-routed IRQ to be */ /* level- or edge-triggered. */ /* Example: 'leveltrigger=4,5,6,20 edgetrigger=21'. */ diff --git a/xen/arch/x86/domain.c b/xen/arch/x86/domain.c index ea14c5855f..3d275206b4 100644 --- a/xen/arch/x86/domain.c +++ b/xen/arch/x86/domain.c @@ -37,6 +37,7 @@ #include #include #include +#include #include #include #include @@ -968,6 +969,8 @@ void domain_relinquish_resources(struct domain *d) BUG_ON(d->cpuset != 0); + physdev_destroy_state(d); + ptwr_destroy(d); /* Release device mappings of other domains */ diff --git a/xen/arch/x86/io_apic.c b/xen/arch/x86/io_apic.c index 3811183d9e..f5c195a565 100644 --- a/xen/arch/x86/io_apic.c +++ b/xen/arch/x86/io_apic.c @@ -615,9 +615,7 @@ static inline int IO_APIC_irq_trigger(int irq) int irq_vector[NR_IRQS] = { FIRST_DEVICE_VECTOR , 0 }; -#ifdef CONFIG_VMX int vector_irq[256]; -#endif int assign_irq_vector(int irq) { @@ -641,10 +639,10 @@ next: panic("ran out of interrupt sources!"); IO_APIC_VECTOR(irq) = current_vector; -#ifdef CONFIG_VMX + vector_irq[current_vector] = irq; - printk("vector_irq[%x] = %d\n", current_vector, irq); -#endif + DPRINTK("vector_irq[%x] = %d\n", current_vector, irq); + return current_vector; } @@ -1627,6 +1625,16 @@ static inline void check_timer(void) panic("IO-APIC + timer doesn't work! pester mingo@redhat.com"); } +#define NR_IOAPIC_BIOSIDS 256 +static u8 ioapic_biosid_to_apic_enum[NR_IOAPIC_BIOSIDS]; +static void store_ioapic_biosid_mapping(void) +{ + u8 apic; + memset(ioapic_biosid_to_apic_enum, ~0, NR_IOAPIC_BIOSIDS); + for ( apic = 0; apic < nr_ioapics; apic++ ) + ioapic_biosid_to_apic_enum[mp_ioapics[apic].mpc_apicid] = apic; +} + /* * * IRQ's that are handled by the old PIC in all cases: @@ -1646,6 +1654,8 @@ static inline void check_timer(void) void __init setup_IO_APIC(void) { + store_ioapic_biosid_mapping(); + enable_IO_APIC(); io_apic_irqs = ~PIC_IRQS; @@ -1949,3 +1959,67 @@ static int __init ioapic_trigger_setup(void) } __initcall(ioapic_trigger_setup); + +int ioapic_guest_read(int apicid, int address, u32 *pval) +{ + u32 val; + int apicenum; + struct IO_APIC_reg_00 reg_00; + unsigned long flags; + + if ( (apicid >= NR_IOAPIC_BIOSIDS) || + ((apicenum = ioapic_biosid_to_apic_enum[apicid]) >= nr_ioapics) ) + return -EINVAL; + + spin_lock_irqsave(&ioapic_lock, flags); + val = io_apic_read(apicenum, address); + spin_unlock_irqrestore(&ioapic_lock, flags); + + /* Rewrite APIC ID to what the BIOS originally specified. */ + if ( address == 0 ) + { + *(int *)®_00 = val; + reg_00.ID = apicid; + val = *(u32 *)®_00; + } + + *pval = val; + return 0; +} + +int ioapic_guest_write(int apicid, int address, u32 val) +{ + int apicenum, pin, irq; + struct IO_APIC_route_entry rte = { 0 }; + unsigned long flags; + + if ( (apicid >= NR_IOAPIC_BIOSIDS) || + ((apicenum = ioapic_biosid_to_apic_enum[apicid]) >= nr_ioapics) ) + return -EINVAL; + + /* Only write to the first half of a route entry. */ + if ( (address < 0x10) || (address & 1) ) + return 0; + + pin = (address - 0x10) >> 1; + + rte.dest.logical.logical_dest = target_cpus(); + *(int *)&rte = val; + + /* Make sure we handle edge/level triggering correctly. */ + if ( !rte.mask ) + { + irq = vector_irq[rte.vector]; + if ( !IO_APIC_IRQ(irq) ) + return 0; + irq_desc[irq].handler = rte.trigger ? + &ioapic_level_irq_type: &ioapic_edge_irq_type; + } + + spin_lock_irqsave(&ioapic_lock, flags); + io_apic_write(apicenum, 0x10 + 2 * pin, *(((int *)&rte) + 0)); + io_apic_write(apicenum, 0x11 + 2 * pin, *(((int *)&rte) + 1)); + spin_unlock_irqrestore(&ioapic_lock, flags); + + return 0; +} diff --git a/xen/arch/x86/physdev.c b/xen/arch/x86/physdev.c new file mode 100644 index 0000000000..9e47826998 --- /dev/null +++ b/xen/arch/x86/physdev.c @@ -0,0 +1,145 @@ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +extern void (*interrupt[])(void); + +extern int ioapic_guest_read(int apicid, int address, u32 *pval); +extern int ioapic_guest_write(int apicid, int address, u32 pval); + +void physdev_modify_ioport_access_range( + struct domain *d, int enable, int port, int num) +{ + int i; + for ( i = port; i < (port + num); i++ ) + (enable ? clear_bit : set_bit)(i, d->arch.iobmp_mask); +} + +void physdev_destroy_state(struct domain *d) +{ + xfree(d->arch.iobmp_mask); + d->arch.iobmp_mask = NULL; +} + +/* Check if a domain controls a device with IO memory within frame @pfn. + * Returns: 1 if the domain should be allowed to map @pfn, 0 otherwise. */ +int domain_iomem_in_pfn(struct domain *p, unsigned long pfn) +{ + return 0; +} + +/* + * Demuxing hypercall. + */ +long do_physdev_op(physdev_op_t *uop) +{ + physdev_op_t op; + long ret; + int irq; + + if ( unlikely(copy_from_user(&op, uop, sizeof(op)) != 0) ) + return -EFAULT; + + switch ( op.cmd ) + { + case PHYSDEVOP_IRQ_UNMASK_NOTIFY: + ret = pirq_guest_unmask(current->domain); + break; + + case PHYSDEVOP_IRQ_STATUS_QUERY: + irq = op.u.irq_status_query.irq; + ret = -EINVAL; + if ( (irq < 0) || (irq >= NR_IRQS) ) + break; + op.u.irq_status_query.flags = 0; + /* Edge-triggered interrupts don't need an explicit unmask downcall. */ + if ( strstr(irq_desc[irq].handler->typename, "edge") == NULL ) + op.u.irq_status_query.flags |= PHYSDEVOP_IRQ_NEEDS_UNMASK_NOTIFY; + ret = 0; + break; + + case PHYSDEVOP_APIC_READ: + ret = -EPERM; + if ( !IS_PRIV(current->domain) ) + break; + ret = ioapic_guest_read( + op.u.apic_op.apic, op.u.apic_op.offset, &op.u.apic_op.value); + break; + + case PHYSDEVOP_APIC_WRITE: + ret = -EPERM; + if ( !IS_PRIV(current->domain) ) + break; + ret = ioapic_guest_write( + op.u.apic_op.apic, op.u.apic_op.offset, op.u.apic_op.value); + break; + + case PHYSDEVOP_ASSIGN_VECTOR: + if ( !IS_PRIV(current->domain) ) + return -EPERM; + + if ( (irq = op.u.irq_op.irq) >= NR_IRQS ) + return -EINVAL; + + op.u.irq_op.vector = assign_irq_vector(irq); + set_intr_gate(op.u.irq_op.vector, interrupt[irq]); + ret = 0; + break; + + case PHYSDEVOP_SET_IOPL: + ret = -EINVAL; + if ( op.u.set_iopl.iopl > 3 ) + break; + ret = 0; + current->arch.iopl = op.u.set_iopl.iopl; + break; + + case PHYSDEVOP_SET_IOBITMAP: + ret = -EINVAL; + if ( !access_ok(op.u.set_iobitmap.bitmap, IOBMP_BYTES) || + (op.u.set_iobitmap.nr_ports > 65536) ) + break; + ret = 0; + current->arch.iobmp = (u8 *)op.u.set_iobitmap.bitmap; + current->arch.iobmp_limit = op.u.set_iobitmap.nr_ports; + break; + default: + ret = -EINVAL; + break; + } + + if ( copy_to_user(uop, &op, sizeof(op)) ) + ret = -EFAULT; + + return ret; +} + +/* Domain 0 has read access to all devices. */ +void physdev_init_dom0(struct domain *d) +{ + /* Access to all I/O ports. */ + d->arch.iobmp_mask = xmalloc_array(u8, IOBMP_BYTES); + BUG_ON(d->arch.iobmp_mask == NULL); + memset(d->arch.iobmp_mask, 0, IOBMP_BYTES); + + set_bit(DF_PHYSDEV, &d->d_flags); +} + + +/* + * Local variables: + * mode: C + * c-set-style: "BSD" + * c-basic-offset: 4 + * tab-width: 4 + * indent-tabs-mode: nil + * End: + */ diff --git a/xen/common/Makefile b/xen/common/Makefile index e832864584..ee312fde92 100644 --- a/xen/common/Makefile +++ b/xen/common/Makefile @@ -4,7 +4,6 @@ include $(BASEDIR)/Rules.mk ifeq ($(TARGET_ARCH),ia64) OBJS := $(subst dom_mem_ops.o,,$(OBJS)) OBJS := $(subst grant_table.o,,$(OBJS)) -OBJS := $(subst physdev.o,,$(OBJS)) endif ifneq ($(perfc),y) diff --git a/xen/common/dom0_ops.c b/xen/common/dom0_ops.c index 5634fc3936..750eb14813 100644 --- a/xen/common/dom0_ops.c +++ b/xen/common/dom0_ops.c @@ -16,7 +16,6 @@ #include #include #include -#include #include extern long arch_do_dom0_op(dom0_op_t *op, dom0_op_t *u_dom0_op); @@ -385,16 +384,6 @@ long do_dom0_op(dom0_op_t *u_dom0_op) } break; - case DOM0_PCIDEV_ACCESS: - { - ret = physdev_pci_access_modify(op->u.pcidev_access.domain, - op->u.pcidev_access.bus, - op->u.pcidev_access.dev, - op->u.pcidev_access.func, - op->u.pcidev_access.enable); - } - break; - case DOM0_SCHED_ID: { op->u.sched_id.sched_id = sched_id(); diff --git a/xen/common/domain.c b/xen/common/domain.c index ea2ea364a5..253a6b102b 100644 --- a/xen/common/domain.c +++ b/xen/common/domain.c @@ -50,10 +50,6 @@ struct domain *do_createdomain(domid_t dom_id, unsigned int cpu) INIT_LIST_HEAD(&d->page_list); INIT_LIST_HEAD(&d->xenpage_list); - /* Per-domain PCI-device list. */ - spin_lock_init(&d->pcidev_lock); - INIT_LIST_HEAD(&d->pcidev_list); - if ( (d->id != IDLE_DOMAIN_ID) && ((init_event_channels(d) != 0) || (grant_table_create(d) != 0)) ) { @@ -106,12 +102,6 @@ struct domain *find_domain_by_id(domid_t dom) } -#ifndef CONFIG_IA64 -extern void physdev_destroy_state(struct domain *d); -#else -#define physdev_destroy_state(_d) ((void)0) -#endif - void domain_kill(struct domain *d) { struct exec_domain *ed; @@ -122,7 +112,6 @@ void domain_kill(struct domain *d) for_each_exec_domain(d, ed) sched_rem_domain(ed); domain_relinquish_resources(d); - physdev_destroy_state(d); put_domain(d); } } diff --git a/xen/common/physdev.c b/xen/common/physdev.c deleted file mode 100644 index d533d93312..0000000000 --- a/xen/common/physdev.c +++ /dev/null @@ -1,832 +0,0 @@ -/**************************************************************************** - * (c) 2004 - Rolf Neugebauer - Intel Research Cambridge - * (c) 2004 - Keir Fraser - University of Cambridge - **************************************************************************** - * - * Description: allows a domain to access devices on the PCI bus - * - * A guest OS may be given access to particular devices on the PCI bus. - * For each domain a list of PCI devices is maintained, describing the - * access mode for the domain. - * - * Guests can figure out the virtualised PCI space through normal PCI config - * register access. Some of the accesses, in particular write accesses, are - * faked. For example the sequence for detecting the IO regions, which requires - * writes to determine the size of the region, is faked out by a very simple - * state machine, preventing direct writes to the PCI config registers by a - * guest. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/* Called by PHYSDEV_PCI_INITIALISE_DEVICE to finalise IRQ routing. */ -extern void pcibios_enable_irq(struct pci_dev *dev); - -#if 0 -#define VERBOSE_INFO(_f, _a...) printk( _f , ## _a ) -#else -#define VERBOSE_INFO(_f, _a...) ((void)0) -#endif - -#ifdef VERBOSE -#define INFO(_f, _a...) printk( _f, ## _a ) -#else -#define INFO(_f, _a...) ((void)0) -#endif - -#define SLOPPY_CHECKING - -#define ACC_READ 1 -#define ACC_WRITE 2 - -/* Upper bounds for PCI-device addressing. */ -#define PCI_BUSMAX 255 -#define PCI_DEVMAX 31 -#define PCI_FUNCMAX 7 -#define PCI_REGMAX 255 - -/* Bit offsets into state. */ -#define ST_BASE_ADDRESS 0 /* bits 0-5: are for base address access */ -#define ST_ROM_ADDRESS 6 /* bit 6: is for rom address access */ - -typedef struct _phys_dev_st { - int flags; /* flags for access etc */ - struct pci_dev *dev; /* the device */ - struct list_head node; /* link to the list */ - struct domain *owner; /* 'owner of this device' */ - int state; /* state for various checks */ -} phys_dev_t; - - -/* Find a device on a per-domain device list. */ -static phys_dev_t *find_pdev(struct domain *d, struct pci_dev *dev) -{ - phys_dev_t *t; - list_for_each_entry ( t, &d->pcidev_list, node ) - if ( dev == t->dev ) - return t; - return NULL; -} - -static int setup_ioport_memory_access(struct domain *d, struct pci_dev *pdev) -{ - struct resource *r; - int i, j; - - if ( d->arch.iobmp_mask == NULL ) - { - if ( (d->arch.iobmp_mask = xmalloc_array(u8, IOBMP_BYTES)) == NULL ) - return -ENOMEM; - memset(d->arch.iobmp_mask, 0xFF, IOBMP_BYTES); - } - - for ( i = 0; i < DEVICE_COUNT_RESOURCE; i++ ) - { - r = &pdev->resource[i]; - if ( r->flags & IORESOURCE_IO ) - { - INFO("Giving domain %u IO resources (%lx - %lx) " - "for device %s\n", d->id, r->start, r->end, pdev->slot_name); - for ( j = r->start; j < r->end + 1; j++ ) - clear_bit(j, d->arch.iobmp_mask); - } - } - - return 0; -} - -void physdev_modify_ioport_access_range( - struct domain *d, int enable, int port, int num) -{ - int i; - for ( i = port; i < (port + num); i++ ) - (enable ? clear_bit : set_bit)(i, d->arch.iobmp_mask); -} - -/* Add a device to a per-domain device-access list. */ -static int add_dev_to_task(struct domain *d, struct pci_dev *dev, int acc) -{ - phys_dev_t *physdev; - int rc; - - if ( (physdev = xmalloc(phys_dev_t)) == NULL ) - { - INFO("Error allocating pdev structure.\n"); - return -ENOMEM; - } - - if ( (rc = setup_ioport_memory_access(d, dev)) < 0 ) - { - xfree(physdev); - return rc; - } - - physdev->dev = dev; - physdev->flags = acc; - physdev->state = 0; - list_add(&physdev->node, &d->pcidev_list); - - if ( acc == ACC_WRITE ) - physdev->owner = d; - - return 0; -} - -void physdev_destroy_state(struct domain *d) -{ - struct list_head *ent; - - xfree(d->arch.iobmp_mask); - d->arch.iobmp_mask = NULL; - - while ( (ent = d->pcidev_list.next) != &d->pcidev_list ) - { - list_del(ent); - xfree(list_entry(ent, phys_dev_t, node)); - } -} - -/* - * physdev_pci_access_modify: - * Allow/disallow access to a specific PCI device. Guests should not be - * allowed to see bridge devices as it needlessly complicates things (one - * possible exception to this is the AGP bridge). - */ -int physdev_pci_access_modify(domid_t dom, int bus, int dev, int func, - int enable) -{ - struct domain *p; - struct pci_dev *pdev; - phys_dev_t *physdev; - int rc = 0; - int oldacc = -1; - - BUG_ON(!IS_PRIV(current->domain)); - - if ( (bus > PCI_BUSMAX) || (dev > PCI_DEVMAX) || (func > PCI_FUNCMAX) ) - return -EINVAL; - - if ( !enable ) - { - INFO("Disallowing access is not yet supported.\n"); - return -EINVAL; - } - - INFO("physdev_pci_access_modify: %02x:%02x:%02x\n", bus, dev, func); - - if ( (p = find_domain_by_id(dom)) == NULL ) - return -ESRCH; - - /* Make the domain privileged. */ - set_bit(DF_PHYSDEV, &p->d_flags); - /* FIXME: MAW for now make the domain REALLY privileged so that it - * can run a backend driver (hw access should work OK otherwise) */ - set_bit(DF_PRIVILEGED, &p->d_flags); - - /* Grant write access to the specified device. */ - if ( (pdev = pci_find_slot(bus, PCI_DEVFN(dev, func))) == NULL ) - { - INFO(" dev does not exist\n"); - rc = -ENODEV; - goto out; - } - - INFO(" add RW %02x:%02x:%02x\n", pdev->bus->number, - PCI_SLOT(pdev->devfn), PCI_FUNC(pdev->devfn)); - - if ( (physdev = find_pdev(p, pdev)) != NULL ) - { - oldacc = physdev->flags; - physdev->flags = ACC_WRITE; - } - else - { - rc = add_dev_to_task(p, pdev, ACC_WRITE); - } - - out: - put_domain(p); - return rc; -} - -/* Check if a domain controls a device with IO memory within frame @pfn. - * Returns: 1 if the domain should be allowed to map @pfn, 0 otherwise. */ -int domain_iomem_in_pfn(struct domain *p, unsigned long pfn) -{ - int ret = 0; - phys_dev_t *phys_dev; - - VERBOSE_INFO("Checking if physdev-capable domain %u needs access to " - "pfn %p\n", p->id, pfn); - - spin_lock(&p->pcidev_lock); - - list_for_each_entry ( phys_dev, &p->pcidev_list, node ) - { - int i; - struct pci_dev *pci_dev = phys_dev->dev; - - for ( i = 0; (i < DEVICE_COUNT_RESOURCE) && (ret == 0); i++ ) - { - struct resource *r = &pci_dev->resource[i]; - - if ( r->flags & IORESOURCE_MEM ) - if ( (r->start >> PAGE_SHIFT) == pfn - || (r->end >> PAGE_SHIFT) == pfn - || ((r->start >> PAGE_SHIFT < pfn) - && (r->end >> PAGE_SHIFT > pfn)) ) - ret = 1; - } - - if ( ret != 0 ) break; - } - - spin_unlock(&p->pcidev_lock); - - VERBOSE_INFO("Domain %u %s mapping of pfn %p\n", - p->id, ret ? "allowed" : "disallowed", pfn); - - return ret; -} - -/* check if a domain has general access to a device */ -static inline int check_dev_acc( - struct domain *d, int bus, int dev, int func, phys_dev_t **pdev) -{ - struct pci_dev *target_dev; - phys_dev_t *target_pdev; - unsigned int target_devfn; - - *pdev = NULL; - - if ( !IS_CAPABLE_PHYSDEV(d) ) - return -EPERM; - - if ( (bus > PCI_BUSMAX) || (dev > PCI_DEVMAX) || (func > PCI_FUNCMAX) ) - return -EINVAL; - - VERBOSE_INFO("b=%x d=%x f=%x ", bus, dev, func); - - /* check target device */ - target_devfn = PCI_DEVFN(dev, func); - target_dev = pci_find_slot(bus, target_devfn); - if ( !target_dev ) - { - VERBOSE_INFO("target does not exist\n"); - return -ENODEV; - } - - /* check access */ - target_pdev = find_pdev(d, target_dev); - if ( !target_pdev ) - { - VERBOSE_INFO("dom has no access to target\n"); - return -EPERM; - } - - *pdev = target_pdev; - return 0; -} - -#ifndef SLOPPY_CHECKING -/* - * Base address registers contain the base address for IO regions. - * The length can be determined by writing all 1s to the register and - * reading the value again. The device will zero the lower unused bits. - * - * to work out the length of the io region a device probe typically does: - * 1) a = read_base_addr_reg() - * 2) write_base_addr_reg(0xffffffff) - * 3) b = read_base_addr_reg() [device zeros lower bits] - * 4) write_base_addr_reg(a) [restore original value] - * this function fakes out step 2-4. *no* writes are made to the device. - * - * phys_dev_t contains a bit field (a bit for each base address register). - * if the bit for a register is set the guest had writen all 1s to the - * register and subsequent read request need to fake out the b. - * if the guest restores the original value (step 4 above) the bit is - * cleared again. If the guest attempts to "restores" a wrong value an - * error is flagged. - */ -static int do_base_address_access(phys_dev_t *pdev, int acc, int idx, - int len, u32 *val) -{ - int st_bit, reg = PCI_BASE_ADDRESS_0 + (idx*4), ret = -EINVAL; - struct pci_dev *dev = pdev->dev; - u32 orig_val, sz; - struct resource *res; - - if ( len != sizeof(u32) ) - { - /* This isn't illegal, but there doesn't seem to be a very good reason - * to do it for normal devices (bridges are another matter). Since it - * would complicate the code below, we don't support this for now. */ - - /* We could set *val to some value but the guest may well be in trouble - * anyway if this write fails. Hopefully the printk will give us a - * clue what went wrong. */ - INFO("Guest %u attempting sub-dword %s to BASE_ADDRESS %d\n", - pdev->owner->id, (acc == ACC_READ) ? "read" : "write", idx); - - return -EPERM; - } - - st_bit = idx + ST_BASE_ADDRESS; - res = &(pdev->dev->resource[idx]); - - if ( acc == ACC_WRITE ) - { - if ( (*val == 0xffffffff) || - ((res->flags & IORESOURCE_IO) && (*val == 0xffff)) ) - { - /* Set bit and return. */ - set_bit(st_bit, &pdev->state); - ret = 0; - } - else - { - /* Assume guest wants to set the base address. */ - clear_bit(st_bit, &pdev->state); - - /* check if guest tries to restore orig value */ - ret = pci_read_config_dword(dev, reg, &orig_val); - if ( (ret == 0) && (*val != orig_val) ) - { - INFO("Guest attempting update to BASE_ADDRESS %d\n", idx); - ret = -EPERM; - } - } - VERBOSE_INFO("fixed pci write: %02x:%02x:%02x reg=0x%02x len=0x%02x" - " val=0x%08x %x\n", - dev->bus->number, PCI_SLOT(dev->devfn), - PCI_FUNC(dev->devfn), reg, len, *val, pdev->state); - } - else if ( acc == ACC_READ ) - { - ret = pci_read_config_dword(dev, reg, val); - if ( (ret == 0) && test_bit(st_bit, &pdev->state) ) - { - /* Cook the value. */ - sz = res->end - res->start; - if ( res->flags & IORESOURCE_MEM ) - { - /* this is written out explicitly for clarity */ - *val = 0xffffffff; - /* bit 0 = 0 */ - /* bit 21 = memory type */ - /* bit 3 = prefetchable */ - /* bit 4-31 width */ - sz = sz >> 4; /* size in blocks of 16 byte */ - sz = ~sz; /* invert */ - *val = *val & (sz << 4); /* and in the size */ - /* use read values for low 4 bits */ - *val = *val | (orig_val & 0xf); - } - else if ( res->flags & IORESOURCE_IO ) - { - *val = 0x0000ffff; - /* bit 10 = 01 */ - /* bit 2-31 width */ - sz = sz >> 2; /* size in dwords */ - sz = ~sz & 0x0000ffff; - *val = *val & (sz << 2); - *val = *val | 0x1; - } - } - VERBOSE_INFO("fixed pci read: %02x:%02x:%02x reg=0x%02x len=0x%02x" - " val=0x%08x %x\n", - dev->bus->number, PCI_SLOT(dev->devfn), - PCI_FUNC(dev->devfn), reg, len, *val, pdev->state); - } - - return ret; -} - - -static int do_rom_address_access(phys_dev_t *pdev, int acc, int len, u32 *val) -{ - int st_bit, ret = -EINVAL; - struct pci_dev *dev = pdev->dev; - u32 orig_val, sz; - struct resource *res; - - if ( len != sizeof(u32) ) - { - INFO("Guest attempting sub-dword %s to ROM_ADDRESS\n", - (acc == ACC_READ) ? "read" : "write"); - return -EPERM; - } - - st_bit = ST_ROM_ADDRESS; - res = &(pdev->dev->resource[PCI_ROM_RESOURCE]); - - if ( acc == ACC_WRITE ) - { - if ( (*val == 0xffffffff) || (*val == 0xfffffffe) ) - { - /* NB. 0xffffffff would be unusual, but we trap it anyway. */ - set_bit(st_bit, &pdev->state); - ret = 0; - } - else - { - /* Assume guest wants simply to set the base address. */ - clear_bit(st_bit, &pdev->state); - - /* Check if guest tries to restore the original value. */ - ret = pci_read_config_dword(dev, PCI_ROM_ADDRESS, &orig_val); - if ( (ret == 0) && (*val != orig_val) ) - { - if ( (*val != 0x00000000) ) - { - INFO("caution: guest tried to change rom address.\n"); - ret = -EPERM; - } - else - { - INFO("guest disabled rom access for %02x:%02x:%02x\n", - dev->bus->number, PCI_SLOT(dev->devfn), - PCI_FUNC(dev->devfn)); - } - } - } - VERBOSE_INFO("fixed pci write: %02x:%02x:%02x reg=0x%02x len=0x%02x" - " val=0x%08x %x\n", - dev->bus->number, PCI_SLOT(dev->devfn), - PCI_FUNC(dev->devfn), PCI_ROM_ADDRESS, len, *val, pdev->state); - } - else if ( acc == ACC_READ ) - { - ret = pci_read_config_dword(dev, PCI_ROM_ADDRESS, val); - if ( (ret == 0) && test_bit(st_bit, &pdev->state) ) - { - /* Cook the value. */ - sz = res->end - res->start; - *val = 0xffffffff; - /* leave bit 0 untouched */ - /* bit 1-10 reserved, harwired to 0 */ - sz = sz >> 11; /* size is in 2KB blocks */ - sz = ~sz; - *val = *val & (sz << 11); - *val = *val | (orig_val & 0x1); - } - VERBOSE_INFO("fixed pci read: %02x:%02x:%02x reg=0x%02x len=0x%02x" - " val=0x%08x %x\n", - dev->bus->number, PCI_SLOT(dev->devfn), - PCI_FUNC(dev->devfn), PCI_ROM_ADDRESS, len, *val, pdev->state); - } - - return ret; - -} -#endif /* SLOPPY_CHECKING */ - -#ifdef CONFIG_PCI -/* - * Handle a PCI config space read access if the domain has access privileges. - */ -static long pci_cfgreg_read(int bus, int dev, int func, int reg, - int len, u32 *val) -{ - int ret; - phys_dev_t *pdev; - - if ( (ret = check_dev_acc(current->domain, bus, dev, func, &pdev)) != 0 ) - { - /* PCI spec states that reads from non-existent devices should return - * all 1s. In this case the domain has no read access, which should - * also look like the device is non-existent. */ - *val = 0xFFFFFFFF; - return ret; - } - - /* Fake out read requests for some registers. */ - switch ( reg ) - { -#ifndef SLOPPY_CHECKING - case PCI_BASE_ADDRESS_0: - ret = do_base_address_access(pdev, ACC_READ, 0, len, val); - break; - - case PCI_BASE_ADDRESS_1: - ret = do_base_address_access(pdev, ACC_READ, 1, len, val); - break; - - case PCI_BASE_ADDRESS_2: - ret = do_base_address_access(pdev, ACC_READ, 2, len, val); - break; - - case PCI_BASE_ADDRESS_3: - ret = do_base_address_access(pdev, ACC_READ, 3, len, val); - break; - - case PCI_BASE_ADDRESS_4: - ret = do_base_address_access(pdev, ACC_READ, 4, len, val); - break; - - case PCI_BASE_ADDRESS_5: - ret = do_base_address_access(pdev, ACC_READ, 5, len, val); - break; - - case PCI_ROM_ADDRESS: - ret = do_rom_address_access(pdev, ACC_READ, len, val); - break; -#endif - - case PCI_INTERRUPT_LINE: - *val = pdev->dev->irq; - ret = 0; - break; - - default: - ret = pci_config_read(0, bus, dev, func, reg, len, val); - VERBOSE_INFO("pci read : %02x:%02x:%02x reg=0x%02x len=0x%02x " - "val=0x%08x\n", bus, dev, func, reg, len, *val); - break; - } - - return ret; -} - - -/* - * Handle a PCI config space write access if the domain has access privileges. - */ -static long pci_cfgreg_write(int bus, int dev, int func, int reg, - int len, u32 val) -{ - int ret; - phys_dev_t *pdev; - - if ( (ret = check_dev_acc(current->domain, bus, dev, func, &pdev)) != 0 ) - return ret; - - /* special treatment for some registers */ - switch (reg) - { -#ifndef SLOPPY_CHECKING - case PCI_BASE_ADDRESS_0: - ret = do_base_address_access(pdev, ACC_WRITE, 0, len, &val); - break; - - case PCI_BASE_ADDRESS_1: - ret = do_base_address_access(pdev, ACC_WRITE, 1, len, &val); - break; - - case PCI_BASE_ADDRESS_2: - ret = do_base_address_access(pdev, ACC_WRITE, 2, len, &val); - break; - - case PCI_BASE_ADDRESS_3: - ret = do_base_address_access(pdev, ACC_WRITE, 3, len, &val); - break; - - case PCI_BASE_ADDRESS_4: - ret = do_base_address_access(pdev, ACC_WRITE, 4, len, &val); - break; - - case PCI_BASE_ADDRESS_5: - ret = do_base_address_access(pdev, ACC_WRITE, 5, len, &val); - break; - - case PCI_ROM_ADDRESS: - ret = do_rom_address_access(pdev, ACC_WRITE, len, &val); - break; -#endif - - default: - if ( pdev->flags != ACC_WRITE ) - { - INFO("pci write not allowed %02x:%02x:%02x: " - "reg=0x%02x len=0x%02x val=0x%08x\n", - bus, dev, func, reg, len, val); - ret = -EPERM; - } - else - { - ret = pci_config_write(0, bus, dev, func, reg, len, val); - VERBOSE_INFO("pci write: %02x:%02x:%02x reg=0x%02x len=0x%02x " - "val=0x%08x\n", bus, dev, func, reg, len, val); - } - break; - } - - return ret; -} - - -static long pci_probe_root_buses(u32 *busmask) -{ - phys_dev_t *pdev; - - memset(busmask, 0, 256/8); - - list_for_each_entry ( pdev, ¤t->domain->pcidev_list, node ) - set_bit(pdev->dev->bus->number, busmask); - - return 0; -} -#endif - -/* - * Demuxing hypercall. - */ -long do_physdev_op(physdev_op_t *uop) -{ - physdev_op_t op; - long ret; - u32 apic, irq; - u32 address, val; - - if ( unlikely(copy_from_user(&op, uop, sizeof(op)) != 0) ) - return -EFAULT; - - switch ( op.cmd ) - { -#ifdef CONFIG_PCI - case PHYSDEVOP_PCI_CFGREG_READ: - ret = pci_cfgreg_read(op.u.pci_cfgreg_read.bus, - op.u.pci_cfgreg_read.dev, - op.u.pci_cfgreg_read.func, - op.u.pci_cfgreg_read.reg, - op.u.pci_cfgreg_read.len, - &op.u.pci_cfgreg_read.value); - break; - - case PHYSDEVOP_PCI_CFGREG_WRITE: - ret = pci_cfgreg_write(op.u.pci_cfgreg_write.bus, - op.u.pci_cfgreg_write.dev, - op.u.pci_cfgreg_write.func, - op.u.pci_cfgreg_write.reg, - op.u.pci_cfgreg_write.len, - op.u.pci_cfgreg_write.value); - break; - - case PHYSDEVOP_PCI_INITIALISE_DEVICE: - if ( (ret = check_dev_acc(current->domain, - op.u.pci_initialise_device.bus, - op.u.pci_initialise_device.dev, - op.u.pci_initialise_device.func, - &pdev)) == 0 ) - pcibios_enable_irq(pdev->dev); - break; - - case PHYSDEVOP_PCI_PROBE_ROOT_BUSES: - ret = pci_probe_root_buses(op.u.pci_probe_root_buses.busmask); - break; -#endif - case PHYSDEVOP_IRQ_UNMASK_NOTIFY: - ret = pirq_guest_unmask(current->domain); - break; - - case PHYSDEVOP_IRQ_STATUS_QUERY: - irq = op.u.irq_status_query.irq; - ret = -EINVAL; - if ( (irq < 0) || (irq >= NR_IRQS) ) - break; - op.u.irq_status_query.flags = 0; - /* Edge-triggered interrupts don't need an explicit unmask downcall. */ - if ( strstr(irq_desc[irq].handler->typename, "edge") == NULL ) - op.u.irq_status_query.flags |= PHYSDEVOP_IRQ_NEEDS_UNMASK_NOTIFY; - ret = 0; - break; -#ifdef __ARCH_HAS_IOAPIC - case PHYSDEVOP_APIC_READ: - if ( !IS_PRIV(current->domain) ) - return -EPERM; - - apic = op.u.apic_op.apic; - address = op.u.apic_op.offset; - ret = -EINVAL; - if (apic >= nr_ioapics) - break; - val = io_apic_read(apic, address); - DPRINTK("ioapic read: %x = %x\n", address, val); - op.u.apic_op.value = val; - ret = 0; - break; - case PHYSDEVOP_APIC_WRITE: - if ( !IS_PRIV(current->domain) ) - return -EPERM; - - apic = op.u.apic_op.apic; - address = op.u.apic_op.offset; - val = op.u.apic_op.value; - ret = -EINVAL; - if (apic >= nr_ioapics) - break; - - DPRINTK("ioapic write: %x = %x\n", address, val); - io_apic_write(apic, address, val); - ret = 0; - break; - case PHYSDEVOP_ASSIGN_VECTOR: - if ( !IS_PRIV(current->domain) ) - return -EPERM; - - irq = op.u.irq_op.irq; - op.u.irq_op.vector = assign_irq_vector(irq); - ret = 0; - break; -#endif - case PHYSDEVOP_SET_IOPL: - ret = -EINVAL; - if ( op.u.set_iopl.iopl > 3 ) - break; - ret = 0; - current->arch.iopl = op.u.set_iopl.iopl; - break; - - case PHYSDEVOP_SET_IOBITMAP: - ret = -EINVAL; - if ( !access_ok(op.u.set_iobitmap.bitmap, IOBMP_BYTES) || - (op.u.set_iobitmap.nr_ports > 65536) ) - break; - ret = 0; - current->arch.iobmp = (u8 *)op.u.set_iobitmap.bitmap; - current->arch.iobmp_limit = op.u.set_iobitmap.nr_ports; - break; - default: - ret = -EINVAL; - break; - } - - if (copy_to_user(uop, &op, sizeof(op))) - ret = -EFAULT; - - return ret; -} - -/* opt_physdev_dom0_hide: list of PCI slots to hide from domain 0. */ -/* Format is '(%02x:%02x.%1x)(%02x:%02x.%1x)' and so on. */ -static char opt_physdev_dom0_hide[200] = ""; -string_param("physdev_dom0_hide", opt_physdev_dom0_hide); - -/* Test if boot params specify this device should NOT be visible to DOM0 - * (e.g. so that another domain can control it instead) */ -static int pcidev_dom0_hidden(struct pci_dev *dev) -{ - char cmp[10] = "(.......)"; - - strncpy(&cmp[1], dev->slot_name, 7); - - if ( strstr(opt_physdev_dom0_hide, dev->slot_name) == NULL ) - return 0; - - return 1; -} - - -/* Domain 0 has read access to all devices. */ -void physdev_init_dom0(struct domain *d) -{ - struct pci_dev *dev; - phys_dev_t *pdev; - - /* Access to all I/O ports. */ - d->arch.iobmp_mask = xmalloc_array(u8, IOBMP_BYTES); - BUG_ON(d->arch.iobmp_mask == NULL); - memset(d->arch.iobmp_mask, 0, IOBMP_BYTES); - - /* Access to all PCI devices. */ - pci_for_each_dev(dev) - { - if ( pcidev_dom0_hidden(dev) ) - { - printk("Hiding PCI device %s from DOM0\n", dev->slot_name); - continue; - } - - pdev = xmalloc(phys_dev_t); - BUG_ON(pdev == NULL); - - pdev->dev = dev; - pdev->flags = ACC_WRITE; - pdev->state = 0; - pdev->owner = d; - list_add(&pdev->node, &d->pcidev_list); - } - - set_bit(DF_PHYSDEV, &d->d_flags); -} - - -/* - * Local variables: - * mode: C - * c-set-style: "BSD" - * c-basic-offset: 4 - * tab-width: 4 - * indent-tabs-mode: nil - * End: - */ diff --git a/xen/drivers/char/serial.c b/xen/drivers/char/serial.c index ba58bc8a16..ebfd44cea8 100644 --- a/xen/drivers/char/serial.c +++ b/xen/drivers/char/serial.c @@ -15,9 +15,12 @@ #include #include #include -#include #include +#ifdef CONFIG_X86 +#include +#endif + /* Config serial port with a string ,DPS,,. */ static char opt_com1[30] = OPT_COM1_STR, opt_com2[30] = OPT_COM2_STR; string_param("com1", opt_com1); @@ -482,10 +485,12 @@ void serial_force_unlock(int handle) void serial_endboot(void) { +#ifdef CONFIG_X86 int i; for ( i = 0; i < ARRAY_SIZE(com); i++ ) if ( UART_ENABLED(&com[i]) ) physdev_modify_ioport_access_range(dom0, 0, com[i].io_base, 8); +#endif } /* diff --git a/xen/include/asm-x86/config.h b/xen/include/asm-x86/config.h index 82608ac93f..719a68202e 100644 --- a/xen/include/asm-x86/config.h +++ b/xen/include/asm-x86/config.h @@ -315,6 +315,4 @@ extern unsigned long xenheap_phys_end; /* user-configurable */ #define ELFSIZE 32 #endif -#define __ARCH_HAS_IOAPIC - #endif /* __X86_CONFIG_H__ */ diff --git a/xen/include/xen/physdev.h b/xen/include/asm-x86/physdev.h similarity index 84% rename from xen/include/xen/physdev.h rename to xen/include/asm-x86/physdev.h index 9f1fc6cde8..0b004d4958 100644 --- a/xen/include/xen/physdev.h +++ b/xen/include/asm-x86/physdev.h @@ -10,8 +10,6 @@ void physdev_modify_ioport_access_range( struct domain *d, int enable, int port, int num ); void physdev_destroy_state(struct domain *d); -int physdev_pci_access_modify( - domid_t dom, int bus, int dev, int func, int enable); int domain_iomem_in_pfn(struct domain *p, unsigned long pfn); long do_physdev_op(physdev_op_t *uop); void physdev_init_dom0(struct domain *d); diff --git a/xen/include/public/dom0_ops.h b/xen/include/public/dom0_ops.h index 828b00f9fe..869a959f6c 100644 --- a/xen/include/public/dom0_ops.h +++ b/xen/include/public/dom0_ops.h @@ -208,19 +208,6 @@ typedef struct { memory_t free_pages; } dom0_physinfo_t; -/* - * Allow a domain access to a physical PCI device - */ -#define DOM0_PCIDEV_ACCESS 23 -typedef struct { - /* IN variables. */ - domid_t domain; - u32 bus; - u32 dev; - u32 func; - u32 enable; -} dom0_pcidev_access_t; - /* * Get the ID of the current scheduler. */ @@ -376,7 +363,6 @@ typedef struct { dom0_pincpudomain_t pincpudomain; dom0_tbufcontrol_t tbufcontrol; dom0_physinfo_t physinfo; - dom0_pcidev_access_t pcidev_access; dom0_sched_id_t sched_id; dom0_shadow_control_t shadow_control; dom0_setdomainmaxmem_t setdomainmaxmem; diff --git a/xen/include/public/physdev.h b/xen/include/public/physdev.h index b17f7d83c2..41ad23bb9f 100644 --- a/xen/include/public/physdev.h +++ b/xen/include/public/physdev.h @@ -1,18 +1,8 @@ -/**************************************************************************** - * (c) 2004 - Rolf Neugebauer - Intel Research Cambridge - * (c) 2004 - Keir Fraser - University of Cambridge - **************************************************************************** - * Description: Interface for domains to access physical devices on the PCI bus - */ #ifndef __XEN_PUBLIC_PHYSDEV_H__ #define __XEN_PUBLIC_PHYSDEV_H__ /* Commands to HYPERVISOR_physdev_op() */ -#define PHYSDEVOP_PCI_CFGREG_READ 0 -#define PHYSDEVOP_PCI_CFGREG_WRITE 1 -#define PHYSDEVOP_PCI_INITIALISE_DEVICE 2 -#define PHYSDEVOP_PCI_PROBE_ROOT_BUSES 3 #define PHYSDEVOP_IRQ_UNMASK_NOTIFY 4 #define PHYSDEVOP_IRQ_STATUS_QUERY 5 #define PHYSDEVOP_SET_IOPL 6 @@ -21,43 +11,6 @@ #define PHYSDEVOP_APIC_WRITE 9 #define PHYSDEVOP_ASSIGN_VECTOR 10 -/* Read from PCI configuration space. */ -typedef struct { - /* IN */ - u32 bus; /* 0 */ - u32 dev; /* 4 */ - u32 func; /* 8 */ - u32 reg; /* 12 */ - u32 len; /* 16 */ - /* OUT */ - u32 value; /* 20 */ -} PACKED physdevop_pci_cfgreg_read_t; /* 24 bytes */ - -/* Write to PCI configuration space. */ -typedef struct { - /* IN */ - u32 bus; /* 0 */ - u32 dev; /* 4 */ - u32 func; /* 8 */ - u32 reg; /* 12 */ - u32 len; /* 16 */ - u32 value; /* 20 */ -} PACKED physdevop_pci_cfgreg_write_t; /* 24 bytes */ - -/* Do final initialisation of a PCI device (e.g., last-moment IRQ routing). */ -typedef struct { - /* IN */ - u32 bus; /* 0 */ - u32 dev; /* 4 */ - u32 func; /* 8 */ -} PACKED physdevop_pci_initialise_device_t; /* 12 bytes */ - -/* Find the root buses for subsequent scanning. */ -typedef struct { - /* OUT */ - u32 busmask[256/32]; /* 0 */ -} PACKED physdevop_pci_probe_root_buses_t; /* 32 bytes */ - typedef struct { /* IN */ u32 irq; /* 0 */ @@ -85,7 +38,7 @@ typedef struct { u32 apic; /* 0 */ u32 offset; /* IN or OUT */ - u64 value; + u32 value; } PACKED physdevop_apic_t; typedef struct { @@ -100,12 +53,6 @@ typedef struct _physdev_op_st u32 cmd; /* 0 */ u32 __pad; /* 4 */ union { /* 8 */ -#ifdef CONFIG_PCI - physdevop_pci_cfgreg_read_t pci_cfgreg_read; - physdevop_pci_cfgreg_write_t pci_cfgreg_write; - physdevop_pci_initialise_device_t pci_initialise_device; - physdevop_pci_probe_root_buses_t pci_probe_root_buses; -#endif physdevop_irq_status_query_t irq_status_query; physdevop_set_iopl_t set_iopl; physdevop_set_iobitmap_t set_iobitmap; diff --git a/xen/include/xen/sched.h b/xen/include/xen/sched.h index 37ab3ff744..266e34e8ec 100644 --- a/xen/include/xen/sched.h +++ b/xen/include/xen/sched.h @@ -129,10 +129,6 @@ struct domain u16 pirq_to_evtchn[NR_PIRQS]; u32 pirq_mask[NR_PIRQS/32]; - /* Physical I/O */ - spinlock_t pcidev_lock; - struct list_head pcidev_list; - unsigned long d_flags; unsigned long vm_assist; -- 2.30.2